/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief UDP connection header
 * \author Antti Maula <antti.maula@tkk.fi>
 */

#ifndef _CONNECTIONUDP_H_
#define _CONNECTIONUDP_H_

#include <sys/types.h>
#include <sys/socket.h> 
#include <sys/poll.h> 
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h> 
#include <string.h>
#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

#define CONNECTIONUDP_OK              0
#define CONNECTIONUDP_ERROR           -1

#define UDPFRAME_SAFE_SIZE            548
#define UDPFRAME_MAX_SIZE             65516

typedef struct {

  int socket_fd; ///< Socket handle
  
  struct hostent *hostEntry; ///< Host entry
  struct sockaddr_in socket_addr; ///< Stores address information

  pthread_mutex_t mutex;
} TConnectionUDP;

/**
 * @param con        Pointer to connection parameters
 *
 */
int connectionUDPCreateListeningSocket(TConnectionUDP *con, int port);


int connectionUDPCreateSendingSocket(TConnectionUDP *con, 
				     const char *host, int port);

/**
 * @param con        Pointer to connection parameters
 *
 */
int connectionUDPInit(TConnectionUDP *con);


/**
 * @param con        Pointer to connection parameters
 *
 */
int connectionUDPDeinit(TConnectionUDP *con);


/**
 * Sends formatted data. Works just like printf()-family, except
 * that the function requires a pointer to Connection.
 * @param con        Pointer to connection parameters
 * @param format     Format parameter
 * @param ...        Arguments
 * @return           Real number of bytes sent, or negative on error.
 */
int connectionUDPSendDataFormatted(TConnectionUDP *con, const char *format, ...);


/**
 * Function that sends raw data over the connection.
 * The function takes care of connection state checking, so
 * it's always safe to call this function.
 * @param con        Pointer to connection parameters
 * @param buffer     Pointer to data buffer to send
 * @param bufLen     Number of bytes to send
 * @return           Real number of bytes sent, or negative on error.
 */
int connectionUDPSendData(TConnectionUDP *con, const unsigned char *buffer, int bufLen);


/**
 * Function that receives raw data over the connection.
 * The function takes care of connection state checking, so
 * it's always safe to call this function.
 * @param con        Pointer to connection parameters
 * @param buffer     Pointer to data buffer to save received data to.
 * @param bufLen     MAXIMUM number of bytes to receive
 * @return           Real number of bytes received, or negative on error.
 */
int connectionUDPReceiveData(TConnectionUDP *con, unsigned char *buffer, int bufLen); 


/**
 * Function that receives raw data over the connection.
 * Connection must be opened with Connect() before this
 * function can be called.
 * The function takes care of connection state checking, so
 * it's always safe to call this function.
 * @param con        Pointer to connection parameters
 * @param buffer     Pointer to data buffer to save received data to.
 * @param bufLen     MAXIMUM number of bytes to receive
 * @param timeout_ms Number of milliseconds to wait for new data. Negative
 *                   value means "forever", and zero is ofcourse "now".
 * @return           Real number of bytes received, or negative on error.
 *                   (The zero value means = no new bytes == timeout)
 */
int connectionUDPReceiveDataTimed(TConnectionUDP *con, 
				  unsigned char *buffer, 
				  int bufLen,
				  int timeout_ms);


#ifdef __cplusplus
}
#endif


#endif //_UDPCONNECTION_H_
